package com.example.chat.view

import android.util.Log
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
import androidx.compose.material.contentColorFor
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.example.chat.model.Emoji
import com.example.chat.repository.EmojiRepository
import com.example.chat.viewmodel.TopicDetailCommands
import com.example.chat.viewmodel.TopicDetailState
import com.example.featuresdk.theme.DemoTheme
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch

@ExperimentalFoundationApi
@Composable
fun EmojiDashboard(commands: TopicDetailCommands, uiState: TopicDetailState, uiConstraints: LayoutConstraints){

    val emojiCategories = remember {
        EmojiRepository.emojiCategories
    }

    val emojiCategoryListState = rememberLazyListState()
    val emojiDashboardListState = rememberLazyListState()
    val coroutineScope = rememberCoroutineScope()
    val emojiCategorySelected = remember { mutableStateOf("Default") }

        //list of emoji categories
        LazyRow(state = emojiCategoryListState) {

            itemsIndexed(emojiCategories) { index, emoji ->
                Image(painter = painterResource(emoji.image),
                    contentDescription = emoji.description,
                    modifier = Modifier
                        .size(uiConstraints.smallEmojiSizeDp.dp)
                        .padding(uiConstraints.emojiPaddingValues)
                        .clip(RoundedCornerShape(4.dp))
                        .clickable {
                            coroutineScope.launch {
                                emojiDashboardListState.animateScrollToItem(index)
                            }
                        }
                        .background(
                            if (emojiCategorySelected.value == emoji.category)
                                Color.White else Color.Transparent
                        )
                )
            }
        }

        LazyRow(state = emojiDashboardListState,modifier = Modifier.background(DemoTheme.colors.secondary)) {
            items(emojiCategories) { emoji ->
                when (emoji.category) {
                    "Default" -> AndroidEmojiDashboard(uiState,uiConstraints) {
                        uiState.chatContent.value += it
                    }
                    "Favorite" -> FavoriteEmojiDashboard(EmojiRepository.getEmojis(emoji.category), uiState,uiConstraints) { image ->
                        commands.sendMessage(image = image)
                    }
                    else -> OtherEmojiDashboard(emoji.category, EmojiRepository.getEmojis(emoji.category), uiState,uiConstraints) { image ->
                        commands.sendMessage(image = image)
                    }
                }
            }
        }

        LaunchedEffect(emojiDashboardListState) {
            snapshotFlow { emojiDashboardListState.firstVisibleItemIndex }
                .distinctUntilChanged()
                .collect {
                    emojiCategorySelected.value = emojiCategories[it].category
                }
        }

        //listen on the scroll progress and automatically scroll to the proper dashboard when scroll completes
        LaunchedEffect(emojiDashboardListState) {
            snapshotFlow { emojiDashboardListState.isScrollInProgress }
                .filter { !it }
                .collect {

                    val offset = emojiDashboardListState.firstVisibleItemScrollOffset
                    if(offset > 0){
                        var index = emojiDashboardListState.firstVisibleItemIndex
                        var nextIndex = index

                        //Log.i("Scroll#1","Index=${index},Offset=${offset},lastIndex=${chatVewModel.emjojiDashboardLastIndex}")

                        coroutineScope.launch {
                            if(EmojiRepository.emjojiDashboardLastIndex == index){
                                //scroll to right on current dashboard
                                if(offset > 120) {
                                    nextIndex++
                                }
                            }else{
                                //scroll to left on previous dashboard
                                if(offset > 950){
                                    nextIndex++
                                }
                            }

                            //Log.i("Scroll#2","NextIndex=${nextIndex}")
                            emojiDashboardListState.animateScrollToItem(nextIndex)
                            EmojiRepository.emjojiDashboardLastIndex = nextIndex
                        }
                    }
                }
        }
}



@ExperimentalFoundationApi
@Composable
fun AndroidEmojiDashboard(uiState: TopicDetailState, uiConstraints: LayoutConstraints, onEmojiClicked:(String)->Unit){

    val emojis = remember {
        EmojiRepository.emoticons
    }

    val emojisUsedRecently = remember {
        EmojiRepository.emojisUsedRecently
    }

    Column(modifier = Modifier
        .padding(uiConstraints.dashboardPaddingValues)
        .width((uiConstraints.screenWithDp - 6).dp)
        .height(uiConstraints.softKeyboardHeightDp.dp)
        .verticalScroll(rememberScrollState())){

        if(emojisUsedRecently.isNotEmpty()){
            MySubtitleText(text = "Recent Use", modifier = Modifier.padding(4.dp), textAlign = TextAlign.Left)

            Row{
                emojisUsedRecently.forEach {
                    TextEmoji(it, uiConstraints,onEmojiClicked)
                }
            }
        }

        MySubtitleText(text = "All Emojis", modifier = Modifier.padding(4.dp), textAlign = TextAlign.Left)

        //Box is required as the container for LazyVerticalGrid to avoid nested scroll exception
        //when the direct parent Column is verticalScroll(...)
        Box(modifier = Modifier
            .width((uiConstraints.screenWithDp - 6).dp)
            .height((uiConstraints.softKeyboardHeightDp - 40).dp)){

            LazyVerticalGrid(
                cells = GridCells.Adaptive(minSize = uiConstraints.mediumEmojiSizeDp.dp),
                contentPadding = uiConstraints.emojiPaddingValues) {
                items (emojis) { emoji->
                    TextEmoji(emoji, uiConstraints){surrogate->
                        onEmojiClicked(surrogate)
                        EmojiRepository.addUsedRecently(emoji)
                    }
                }
            }
        }
    }
}

//fontSize = TextUnit(8f, TextUnitType.Em
//@ExperimentalUnitApi
@Composable
 fun TextEmoji(emoji: Emoji, uiConstraints: LayoutConstraints, onEmojiClicked:(String)->Unit){

    Box(modifier = Modifier.size(uiConstraints.smallEmojiSizeDp.dp)){
        Text( text = emoji.surrogate,
            modifier = Modifier.clickable { onEmojiClicked(emoji.surrogate) },
            style = DemoTheme.typography.textEmoji
        )
    }
}

@Composable
fun CustomEmoji(emojiKey:String, emojiRes:Int, uiConstraints: LayoutConstraints, onEmojiClicked:(Int)->Unit){
    Image(painter = painterResource(emojiRes),
        contentDescription = emojiKey,
        modifier = Modifier
            .size(uiConstraints.largeEmojiSizeDp.dp)
            .padding(uiConstraints.emojiPaddingValues)
            .clip(RoundedCornerShape(4.dp))
            .clickable {
                onEmojiClicked(emojiRes)
            }
    )
}

@ExperimentalFoundationApi
@Composable
fun FavoriteEmojiDashboard(emojis:Map<String,Int>, uiState: TopicDetailState, uiConstraints: LayoutConstraints, onEmojiClicked:(Int)->Unit){

    Column(modifier = Modifier
        .padding(uiConstraints.dashboardPaddingValues)
        .width((uiConstraints.screenWithDp - 6).dp)
        .height(uiConstraints.softKeyboardHeightDp.dp)){

        MySubtitleText(text = "Favorite", modifier = Modifier.padding(4.dp), textAlign = TextAlign.Left)

        LazyVerticalGrid(
            cells = GridCells.Adaptive(minSize = uiConstraints.largeEmojiSizeDp.dp),
            contentPadding = PaddingValues(0.dp,0.dp,0.dp,0.dp)
        ) {
            item{
                CustomEmoji("Add",com.example.chat.R.drawable.ic_add, uiConstraints){
                    //TODO: launch the emoji search screen
                    Log.i("CustomEmoji","launch search screen for custom emojis")
                }
            }
            items(emojis.entries.toList()) { entry ->
                CustomEmoji(entry.key,entry.value, uiConstraints, onEmojiClicked)
            }
        }
    }
}


@ExperimentalFoundationApi
@Composable
 fun OtherEmojiDashboard(category:String, emojis:Map<String,Int>, uiState: TopicDetailState, uiConstraints: LayoutConstraints, onEmojiClicked:(Int)->Unit){

    Column(modifier = Modifier
        .padding(uiConstraints.dashboardPaddingValues)
        .width((uiConstraints.screenWithDp - 6).dp)
        .height(uiConstraints.softKeyboardHeightDp.dp)){

        Row(horizontalArrangement = Arrangement.SpaceBetween) {
            MySubtitleText(text = category,
                modifier = Modifier
                    .padding(4.dp)
                    .width((uiConstraints.screenWithDp / 2).dp)
                ,textAlign = TextAlign.Left)

            MySubtitleText(text = "more >", modifier = Modifier
                .padding(4.dp, 4.dp, 4.dp, 4.dp)
                .width((uiConstraints.screenWithDp / 2 - 30).dp))
        }

        LazyVerticalGrid(
            cells = GridCells.Adaptive(minSize = uiConstraints.largeEmojiSizeDp.dp),
            contentPadding = PaddingValues(0.dp,0.dp,0.dp,0.dp)
        ) {

            items (emojis.entries.toList()) { entry->

                Column(horizontalAlignment = Alignment.CenterHorizontally) {
                    CustomEmoji(entry.key,entry.value, uiConstraints,onEmojiClicked)

                    MySubtitleText(text = entry.key.substring(0,4),
                        modifier = Modifier.padding(0.dp, 1.dp)
                    )
                }
            }
        }
    }
}

@Composable
fun MySubtitleText(text: String, modifier: Modifier, textAlign: TextAlign = TextAlign.Right){
    Text(text = text, modifier = modifier,
        style = DemoTheme.typography.subtitle,
        color = contentColorFor(DemoTheme.colors.secondary),
        textAlign = textAlign)
}